﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ProjectActioner.cs" company="DissingNelleman">
//   
// All rights reserved. </copyright>
// <summary>
//   The project actioner.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace ServiceLibrary.Actioners.Activities
{
    using System;
    using System.Collections.Generic;
    using System.Linq;

    using NHibernate;

    using ServiceLibrary.Models.Base;
    using ServiceLibrary.Models.Domain;
    using ServiceLibrary.Services.Commands;
    using ServiceLibrary.Services.Queries;
    using ServiceLibrary.Services.Results;

    /// <summary>
    /// The project actioner.
    /// </summary>
    internal class ProjectActioner : ActionerBase
    {
        #region Constructors and Destructors

        /// <summary>
        /// Initializes a new instance of the <see cref="ProjectActioner"/> class.
        /// </summary>
        /// <param name="session">
        /// The session.
        /// </param>
        /// <param name="activeUser">
        /// The active user.
        /// </param>
        public ProjectActioner(ISession session, User activeUser)
            : base(session, activeUser)
        {
        }

        #endregion

        #region Public Methods and Operators

        /// <summary>
        /// The create project.
        /// </summary>
        /// <param name="proj">
        /// The proj.
        /// </param>
        /// <returns>
        /// The <see cref="Guid"/>.
        /// </returns>
        public Guid CreateProject(Project proj)
        {
            proj.CreatedDateTime = DateTime.Now;
            this.Session.Save(proj);
            this.Log.CreateLogEntry(proj.ID, "Projekt '{0}' blev oprettet.", Enums.LogEntryType.Project);

            return proj.ID;
        }

        /// <summary>
        /// The create project.
        /// </summary>
        /// <param name="cmd">
        /// The cmd.
        /// </param>
        public void CreateProject(CreateProjectCommand cmd)
        {
            if (cmd.Project != null)
            {
                var proj = new Project { ID = cmd.Project.ID, Name = cmd.Project.Name };
                CreateProject(proj);
            }
        }

        /// <summary>
        /// The execute search query.
        /// </summary>
        /// <param name="projectQuery">
        /// The project query.
        /// </param>
        /// <returns>
        /// The <see cref="IResult"/>.
        /// </returns>
        public IResult ExecuteSearchQuery(ProjectQuery projectQuery)
        {
            SearchSettings settings = projectQuery.Settings;
            var result = new ProjectResult();

            IQueryOver<Project, Project> search = this.Session.QueryOver<Project>();
            this.ApplyDefaultCriterias(projectQuery.Settings, search);

            result.TotalRowCount = search.RowCount();
            IList<Project> list = ApplySkipAndTake(settings, search);

            if (list.Any())
            {
                list = list.OrderBy(x => x.Name).ToList();
                foreach (Project project in list)
                {
                    result.List.Add(Services.Dto.Project.Convert(project));
                }
            }

            return result;
        }

        #endregion

        #region Methods

        /// <summary>
        /// The create default projects.
        /// </summary>
        internal void CreateDefaultProjects()
        {
            IList<Project> existingProjects = this.Session.QueryOver<Project>().List();

            var defaultProjectNames = new List<string>
                                          {
                                              "ProTech", 
                                              "PatientAtHome", 
                                              "Opi-puljen", 
                                              "WT 2.0", 
                                              "HANC", 
                                              "IHL", 
                                              "Nordic Innovation", 
                                              "Gamelab4health", 
                                              "VIP", 
                                              "Lån en leder", 
                                              "Power Push", 
                                              "6 kommuner", 
                                              "Andet"
                                          };

            foreach (var newProj in from proj in defaultProjectNames let alreadyExists = (from p in existingProjects where p.Name.Equals(proj) select p).Any() where !alreadyExists select new Project { ID = Guid.NewGuid(), Name = proj, CreatedDateTime = DateTime.Now })
            {
                this.CreateProject(newProj);
            }
        }

        /// <summary>
        /// The delete project.
        /// </summary>
        /// <param name="cmd">
        /// The cmd.
        /// </param>
        internal void DeleteProject(DeleteProjectCommand cmd)
        {
            var proj = this.Session.Get<Project>(cmd.Dto);

            if (proj != null)
            {
                int projectUsage = this.Session.QueryOver<ProjectMeeting>().Where(x => x.Owner.ID == proj.ID).RowCount();
                if (projectUsage == 0)
                {
                    this.Session.Delete(proj);
                }
            }
        }

        /// <summary>
        /// The update project.
        /// </summary>
        /// <param name="cmd">
        /// The cmd.
        /// </param>
        internal void UpdateProject(UpdateProjectCommand cmd)
        {
            if (cmd.Dto != null)
            {
                var proj = this.Session.Get<Project>(cmd.Dto.ID);
                if (proj != null)
                {
                    proj.Name = cmd.Dto.Name;
                    this.Session.Update(proj);
                }
            }
        }

        #endregion
    }
}